package cn.pink.gatesrv;

import cn.pink.core.gen.proxy.RPCProxyBase;
import cn.pink.core.*;
import cn.pink.common.support.tools.node.NodeTool;
import cn.pink.core.support.Param;
import cn.pink.core.support.Utils;
import cn.pink.core.support.function.*;
import cn.pink.core.Chunk;
import cn.pink.core.gen.IronGenFile;


@IronGenFile
public class RPCProxy {
	public static final class GateServiceProxy extends RPCProxyBase {
		public final class EnumCall{
			public static final int CN_PINK_GATESRV_GATESERVICE_DEFAULTHANDLER_STRING = 1;
		}

		public static final String DIST_NAME = "GateService";

		private CallPoint remote;
		private Port localPort;

		private static NodeType nodeType = NodeType.GATE;
		
		/**
		 * 私有构造函数
		 * 防止实例被私自创建 必须通过newInstance函数
		 */
		private GateServiceProxy() {}
	
		/**
		 * 伪随机随机获取远程实例
		 * 优先获取本地实例
		 */
		public static GateServiceProxy newInstance() {
			NodeInfo nodeInfo = NodeTool.getInstance().getRandomNode(nodeType);
			return createInstance(nodeInfo.getNodeId(), nodeInfo.getPortId(), DIST_NAME);
		}

		public static GateServiceProxy newInstance(String nodeId, String portId) {
			return createInstance(nodeId, portId, DIST_NAME);
		}

		/**
		 * 创建实例
		 */
		private static GateServiceProxy createInstance(String node, String port, Object id) {
			GateServiceProxy inst = new GateServiceProxy();
			inst.localPort = Port.getCurrent();
			inst.remote = new CallPoint(node, port, id);
			
			return inst;
		}
		
		/**
		 * 监听返回值
		 */
		public void listenResult(IronFunction2<Param, Param> method, Object...context) {
			listenResult(method, new Param(context));
		}
		
		/**
		 * 监听返回值
		 */
		public void listenResult(IronFunction2<Param, Param> method, Param context) {
			context.put("_callerInfo", remote.callerInfo);
			localPort.listenResult(method, context);
		}
		
		
		public void listenResult(IronFunction3<Boolean, Param, Param> method, Object...context) {
			listenResult(method, new Param(context));
		}
		
		public void listenResult(IronFunction3<Boolean, Param, Param> method, Param context) {
			context.put("_callerInfo", remote.callerInfo);
			localPort.listenResult(method, context);
		}
		
		public void defaultHandler(String arg0) {
			remote.callerInfo = Utils.getCallerInfo();
			localPort.call(remote, EnumCall.CN_PINK_GATESRV_GATESERVICE_DEFAULTHANDLER_STRING, new Object[]{ arg0 });
		}
		
		public Call makeCall_defaultHandler(String arg0) {
			Call call = localPort.makeCall(remote, EnumCall.CN_PINK_GATESRV_GATESERVICE_DEFAULTHANDLER_STRING, new Object[]{ arg0 });
			call.to.callerInfo = Utils.getCallerInfo();
			
			return call;
		}	
	}
	
	public static final class SessionServiceProxy extends RPCProxyBase {
		public final class EnumCall{
			public static final int CN_PINK_GATESRV_SESSIONSERVICE_CLOSEIMMEDIATE = 1;
			public static final int CN_PINK_GATESRV_SESSIONSERVICE_LOGINRESULT_STRING_CALLPOINT_CHUNK = 2;
			public static final int CN_PINK_GATESRV_SESSIONSERVICE_SENDMSG_INT_CHUNK = 3;
		}

		public static final String DIST_NAME = "SessionService";

		private CallPoint remote;
		private Port localPort;

		private static NodeType nodeType = NodeType.NONE;
		
		/**
		 * 私有构造函数
		 * 防止实例被私自创建 必须通过newInstance函数
		 */
		private SessionServiceProxy() {}
	

        /**
		 * 获取实例
		 */
//		public static SessionServiceProxy newInstance(String portId) {
//			return createInstance(nodeId, portId, DIST_NAME);
//		}

		/**
		 * 获取实例
		 */
		public static SessionServiceProxy newInstance(CallPoint targetPoint) {
			return createInstance(targetPoint.nodeId, targetPoint.portId, targetPoint.servId);
		}
		
		/**
		 * 获取实例
		 */
		public static SessionServiceProxy newInstance(String node, String port, Object id) {
			return createInstance(node, port, id);
		}

		/**
		 * 创建实例
		 */
		private static SessionServiceProxy createInstance(String node, String port, Object id) {
			SessionServiceProxy inst = new SessionServiceProxy();
			inst.localPort = Port.getCurrent();
			inst.remote = new CallPoint(node, port, id);
			
			return inst;
		}
		
		/**
		 * 监听返回值
		 */
		public void listenResult(IronFunction2<Param, Param> method, Object...context) {
			listenResult(method, new Param(context));
		}
		
		/**
		 * 监听返回值
		 */
		public void listenResult(IronFunction2<Param, Param> method, Param context) {
			context.put("_callerInfo", remote.callerInfo);
			localPort.listenResult(method, context);
		}
		
		
		public void listenResult(IronFunction3<Boolean, Param, Param> method, Object...context) {
			listenResult(method, new Param(context));
		}
		
		public void listenResult(IronFunction3<Boolean, Param, Param> method, Param context) {
			context.put("_callerInfo", remote.callerInfo);
			localPort.listenResult(method, context);
		}
		
		public void closeImmediate() {
			remote.callerInfo = Utils.getCallerInfo();
			localPort.call(remote, EnumCall.CN_PINK_GATESRV_SESSIONSERVICE_CLOSEIMMEDIATE, new Object[]{  });
		}
		public void loginResult(String arg0, CallPoint arg1, Chunk arg2) {
			remote.callerInfo = Utils.getCallerInfo();
			localPort.call(remote, EnumCall.CN_PINK_GATESRV_SESSIONSERVICE_LOGINRESULT_STRING_CALLPOINT_CHUNK, new Object[]{ arg0, arg1, arg2 });
		}
		public void sendMsg(int arg0, Chunk arg1) {
			remote.callerInfo = Utils.getCallerInfo();
			localPort.call(remote, EnumCall.CN_PINK_GATESRV_SESSIONSERVICE_SENDMSG_INT_CHUNK, new Object[]{ arg0, arg1 });
		}
		
		public Call makeCall_closeImmediate() {
			Call call = localPort.makeCall(remote, EnumCall.CN_PINK_GATESRV_SESSIONSERVICE_CLOSEIMMEDIATE, new Object[]{  });
			call.to.callerInfo = Utils.getCallerInfo();
			
			return call;
		}	
		public Call makeCall_loginResult(String arg0, CallPoint arg1, Chunk arg2) {
			Call call = localPort.makeCall(remote, EnumCall.CN_PINK_GATESRV_SESSIONSERVICE_LOGINRESULT_STRING_CALLPOINT_CHUNK, new Object[]{ arg0, arg1, arg2 });
			call.to.callerInfo = Utils.getCallerInfo();
			
			return call;
		}	
		public Call makeCall_sendMsg(int arg0, Chunk arg1) {
			Call call = localPort.makeCall(remote, EnumCall.CN_PINK_GATESRV_SESSIONSERVICE_SENDMSG_INT_CHUNK, new Object[]{ arg0, arg1 });
			call.to.callerInfo = Utils.getCallerInfo();
			
			return call;
		}	
	}
	
}